package untils

import (
	"context"
	"fmt"
	"time"
)

// WithTimeout 为操作添加超时控制
func WithTimeout(ctx context.Context, timeout time.Duration, operation func(context.Context) error) error {
	ctx, cancel := context.WithTimeout(ctx, timeout)
	defer cancel()

	done := make(chan error, 1)

	go func() {
		done <- operation(ctx)
	}()

	select {
	case err := <-done:
		return err
	case <-ctx.Done():
		return fmt.Errorf("操作超时: %v", ctx.Err())
	}
}

// CircuitBreaker 熔断器模式
type CircuitBreaker struct {
	MaxFailures int
	Timeout     time.Duration
	ResetTime   time.Duration

	failures    int
	lastFailure time.Time
	state       string // "closed", "open", "half-open"
}

// Call 执行操作，带熔断保护
func (cb *CircuitBreaker) Call(operation func() error) error {
	if cb.state == "open" {
		if time.Since(cb.lastFailure) > cb.ResetTime {
			cb.state = "half-open"
		} else {
			return fmt.Errorf("熔断器开启，拒绝请求")
		}
	}

	err := operation()
	if err != nil {
		cb.failures++
		cb.lastFailure = time.Now()

		if cb.failures >= cb.MaxFailures {
			cb.state = "open"
		}
		return err
	}

	// 成功时重置状态
	if cb.state == "half-open" {
		cb.state = "closed"
		cb.failures = 0
	}

	return nil
}
